#!/usr/bin/env python3
"""
地平线X3 SOC端轻量级监控脚本
仅使用标准库，不依赖外部包
"""

import time
import json
import os
from datetime import datetime

class LightSystemMonitor:
    def __init__(self, log_file="/userdata/ros2_log/system_monitor.log"):
        self.log_file = log_file
        self.setup_logging()
        
    def setup_logging(self):
        """设置日志文件"""
        # 确保日志目录存在
        os.makedirs(os.path.dirname(self.log_file) if os.path.dirname(self.log_file) else '.', exist_ok=True)
        
    def read_proc_stat(self):
        """读取/proc/stat文件获取CPU信息"""
        with open('/proc/stat', 'r') as f:
            lines = f.readlines()
            for line in lines:
                if line.startswith('cpu '):
                    parts = line.split()
                    # user, nice, system, idle, iowait, irq, softirq
                    total_time = sum(int(x) for x in parts[1:8])
                    idle_time = int(parts[4])
                    return total_time, idle_time
        return 0, 0
    
    def read_proc_meminfo(self):
        """读取/proc/meminfo获取内存信息"""
        meminfo = {}
        try:
            with open('/proc/meminfo', 'r') as f:
                for line in f:
                    parts = line.split()
                    if len(parts) >= 2:
                        key = parts[0].rstrip(':')
                        value = int(parts[1])
                        meminfo[key] = value
        except:
            pass
        return meminfo
    
    def get_system_cpu_info(self):
        """获取系统CPU使用率"""
        total1, idle1 = self.read_proc_stat()
        time.sleep(0.5)  # 等待0.5秒
        total2, idle2 = self.read_proc_stat()
        
        total_diff = total2 - total1
        idle_diff = idle2 - idle1
        
        cpu_percent = 100.0 * (total_diff - idle_diff) / total_diff if total_diff > 0 else 0
        
        # 获取负载平均值
        try:
            with open('/proc/loadavg', 'r') as f:
                load_avg = f.read().split()[:3]
                load_avg = [float(x) for x in load_avg]
        except:
            load_avg = [0, 0, 0]
            
        # 获取内存信息
        meminfo = self.read_proc_meminfo()
        mem_total = meminfo.get('MemTotal', 1)
        mem_available = meminfo.get('MemAvailable', mem_total)
        mem_used = mem_total - mem_available
        memory_percent = 100.0 * mem_used / mem_total if mem_total > 0 else 0
        
        return {
            'cpu_total_percent': round(cpu_percent, 2),
            'load_avg': load_avg,
            'memory_percent': round(memory_percent, 2),
            'memory_used_mb': round(mem_used / 1024, 2),
            'memory_total_mb': round(mem_total / 1024, 2)
        }
    
    def get_top_processes(self, top_n=10):
        """获取CPU占用最高的进程"""
        processes = []
        
        # 遍历/proc目录下的进程
        try:
            for pid in os.listdir('/proc'):
                if pid.isdigit():
                    try:
                        # 读取进程状态
                        with open(f'/proc/{pid}/stat', 'r') as f:
                            stat_data = f.read().split()
                        
                        # 读取进程命令行
                        with open(f'/proc/{pid}/cmdline', 'r') as f:
                            cmdline = f.read().replace('\x00', ' ').strip()
                        
                        if not cmdline:
                            cmdline = stat_data[1]  # 进程名
                            
                        # 计算CPU使用率 (简化版本)
                        utime = int(stat_data[13])
                        stime = int(stat_data[14])
                        total_time = utime + stime
                        
                        processes.append({
                            'pid': int(pid),
                            'name': stat_data[1],
                            'cpu_percent': total_time / 100,  # 简化计算
                            'cmdline': cmdline
                        })
                        
                    except (IOError, IndexError):
                        continue
                        
        except OSError:
            pass
        
        # 按CPU使用率排序并返回前top_n个
        processes.sort(key=lambda x: x['cpu_percent'], reverse=True)
        return processes[:top_n]
    
    def monitor(self):
        """开始监控"""
        print("开始系统资源监控...")
        print("按 Ctrl+C 停止监控")
        
        try:
            while True:
                timestamp = datetime.now().isoformat()
                
                # 获取系统信息
                system_info = self.get_system_cpu_info()
                
                # 获取占用CPU最高的进程
                top_processes = self.get_top_processes(10)
                
                # 构建日志记录
                log_data = {
                    'timestamp': timestamp,
                    'system_info': system_info,
                    'top_processes': top_processes
                }
                
                # 记录到日志文件
                with open(self.log_file, 'a', encoding='utf-8') as f:
                    f.write(f"{datetime.now().strftime('%Y-%m-%d %H:%M:%S')} - {json.dumps(log_data, ensure_ascii=False)}\n")
                
                print(f"[{timestamp}] CPU: {system_info['cpu_total_percent']}% | "
                      f"Memory: {system_info['memory_percent']}% | "
                      f"Load: {system_info['load_avg'][0]:.2f}")
                
                # 控制采集频率：每秒2帧
                time.sleep(0.5)
                
        except KeyboardInterrupt:
            print("\n监控已停止")

def main():
    monitor = LightSystemMonitor()
    monitor.monitor()

if __name__ == "__main__":
    main()